# -*- coding: utf-8 -*-
# Created by shu2015626 on 2019-7-3
"""
在后台通过配置该任务的参数（需要执行的python文件，和类）实现动态配置任务的效果
这种方法会污染当前的python运行环境。不建议！！！！
这里只是因为想到了这个方法，实现了放在这。
不建议使用！！！不建议使用！！！不建议使用！！！
"""
import re
import logging
from celery import shared_task
from apps.CeleryTaskBase import CeleryTaskBase

logger = logging.getLogger("tasks")


@shared_task(bind=True, name="common.compile_common_task", base=CeleryTaskBase, max_retries=3,
             default_retry_delay=10 * 60, retry_kwargs={'max_retries': 3, 'countdown': 10 * 60})
def compile_common_task(self, business_path: str, task_cls_name: str):
    """
    存在污染当前python运行环境的风险！
    不建议使用！！！不建议使用！！！不建议使用！！！
    :param self:
    :param business_path: 业务所在文件的全路径
    :param task_cls_name: 业务文件中需要执行的类名
    :return:
    """
    try:
        res = {}
        with open(business_path, 'rt', encoding='utf-8') as f:
            # 编译py文件的中的代码
            bytes_code = compile(f.read(), '', 'exec')
            # 执行代码对象，将其中的类加载到globals()中。
            exec(bytes_code, globals())
            # 执行具体的任务
            cls = globals()[task_cls_name]
            result = cls().run()
            # 将对象删除
            del globals()[task_cls_name]
            # 获取执行的文件名称，主要是在结果中表明是哪个文件
            operate_file = re.split(r"[/\\]", business_path.strip())[-1]
            if operate_file and "." in operate_file:
                self.request.operate_file = operate_file
            res['result'] = result
            res['hostname'] = self.request.hostname
            res['business_path'] = business_path
            res['task_cls_name'] = task_cls_name
            res['task_name'] = self.request.task
            res['task_id'] = self.request.id
        # print('res: ', res)
        return res
    finally:
        try:
            del globals()[task_cls_name]
        except Exception as e:
            pass
